package com.inspectortime.util;

import java.io.IOException;
import java.net.URL;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Helper class which is used to located DTD's contained on the classpath
 * 
 * See http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/EntityResolver.html
 * 
 * @author mkvalsvik
 * 
 */
public class ClassPathEntityResolver implements EntityResolver {

    private static Log log = LogFactory.getLog(ClassPathEntityResolver.class);

    /**
     * Assumes the systemId looks something like this:
     * "file:///nds-registration-mapping.dtd" Will strip away everything but the
     * filename and try to resolve via classpath
     * 
     * @param publicId
     * @param systemId
     * @return the input source if found
     * @throws SAXException
     * @throws IOException
     * 
     */
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {

        // Crude, slow, but effective way to determine if an actual DTD file
        // exists on the classpath
        URL paramURL = new URL(systemId);
        String[] possibleResourceNames = { paramURL.getPath(), paramURL.getHost(), paramURL.getFile(),
            paramURL.getAuthority(), paramURL.getProtocol(), paramURL.getUserInfo(), paramURL.getQuery() };
        URL actualURL = null;
        boolean found = false;
        for (int i = 0; i < possibleResourceNames.length; i++) {
            if (possibleResourceNames[i] == null || possibleResourceNames[i].equals("")) {
                continue;
            }
            actualURL = ClassUtils.getResource(this.getClass(), possibleResourceNames[i]);
            if (actualURL != null) {
                found = true;
                break;
            }
        }
        if (!found) {
            throw new IOException(this.getClass().getName() + ": Could not resolve system id " + systemId
                    + ", resource not found on classpath");
        }

        log.debug("Resolved system id " + systemId + " to file: " + actualURL.getFile());
        return new InputSource(actualURL.openStream());
    }

    public String toString() {
        return this.getClass().getName();
    }
}
